package cn.csc.module.distribute.service.downline;

import cn.csc.framework.common.pojo.PageResult;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.csc.framework.mybatis.core.util.MyBatisUtils;
import cn.csc.framework.security.core.util.SecurityFrameworkUtils;
import cn.csc.module.distribute.api.downline.dto.CreateDistributeDownlineReqDTO;
import cn.csc.module.distribute.controller.admin.downline.vo.*;
import cn.csc.module.distribute.controller.app.distributor.vo.AppDistributorReqVO;
import cn.csc.module.distribute.controller.app.downline.vo.AppDistributeDownlineReqVO;
import cn.csc.module.distribute.convert.downline.DistributeDownlineConvert;
import cn.csc.module.distribute.dal.dataobject.distributor.DistributorDO;
import cn.csc.module.distribute.dal.dataobject.downline.DistributeDownlineDO;
import cn.csc.module.distribute.dal.mysql.distributor.DistributorMapper;
import cn.csc.module.distribute.dal.mysql.downline.DistributeDownlineMapper;
import cn.csc.module.member.api.user.MemberUserApi;
import cn.csc.module.member.api.user.dto.MemberUserRespDTO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.Collection;
import java.util.List;

import static cn.csc.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.csc.module.distribute.enums.ErrorCodeConstants.DISTRIBUTOR_NOT_EXISTS;
import static cn.csc.module.distribute.enums.ErrorCodeConstants.DOWNLINE_NOT_EXISTS;

/**
 * 分销下线信息 Service 实现类
 *
 * @author liuchuang
 */
@Service
@Validated
public class DistributeDownlineServiceImpl extends ServiceImpl<DistributeDownlineMapper,DistributeDownlineDO> implements DistributeDownlineService {

    @Resource
    private DistributeDownlineMapper downlineMapper;

    @Resource
    private DistributorMapper distributorMapper;

    @Resource
    private MemberUserApi memberUserApi;

    @Override
    public BigInteger createDownline(DistributeDownlineCreateReqVO createReqVO) {
        // 插入
        DistributeDownlineDO downline = DistributeDownlineConvert.INSTANCE.convert(createReqVO);
        downlineMapper.insert(downline);
        // 返回
        return downline.getId();
    }

    @Override
    public void updateDownline(DistributeDownlineUpdateReqVO updateReqVO) {
        // 校验存在
        validateDownlineExists(updateReqVO.getId());
        // 更新
        DistributeDownlineDO updateObj = DistributeDownlineConvert.INSTANCE.convert(updateReqVO);
        downlineMapper.updateById(updateObj);
    }

    @Override
    public void deleteDownline(BigInteger id) {
        // 校验存在
        validateDownlineExists(id);
        // 删除
        downlineMapper.deleteById(id);
    }

    private void validateDownlineExists(BigInteger id) {
        if (downlineMapper.selectById(id) == null) {
            throw exception(DOWNLINE_NOT_EXISTS);
        }
    }

    @Override
    public DistributeDownlineDO getDownline(BigInteger id) {
        return downlineMapper.selectById(id);
    }

    @Override
    public List<DistributeDownlineDO> getDownlineList(Collection<BigInteger> ids) {
        return downlineMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<DistributeDownlineDO> getDownlinePage(DistributeDownlinePageReqVO pageReqVO) {
        return downlineMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<DistributeDownlineDO> getAppDownlinePage(AppDistributeDownlineReqVO pageReqVO) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        AppDistributorReqVO reqVO = new AppDistributorReqVO();
        reqVO.setUserId(new BigInteger(String.valueOf(userId)));
        reqVO.setStatus(1);
        DistributorDO distributorDO = distributorMapper.getDistributorByUserId(reqVO);
        if(distributorDO == null)
             throw exception(DISTRIBUTOR_NOT_EXISTS);
        pageReqVO.setParentId(distributorDO.getId());
        return downlineMapper.selectAppPage(pageReqVO);
    }

    @Override
    public List<DistributeDownlineDO> getDownlineList(DistributeDownlineExportReqVO exportReqVO) {
        return downlineMapper.selectList(exportReqVO);
    }

    @Transactional
    @Override
    public int relate(CreateDistributeDownlineReqDTO reqDTO) {
        DistributorDO distributorDO = distributorMapper.selectByInviteCode(reqDTO.getInviteCode());
        DistributeDownlineDO distributeDownlineDO = DistributeDownlineConvert.INSTANCE.convert1(reqDTO);
        distributeDownlineDO.setParentId(distributorDO.getId());
        DistributeDownlineDO downlineDO = downlineMapper.selectByChildId(distributeDownlineDO.getChildId());
        if (downlineDO == null) {
            int count = downlineMapper.insert(distributeDownlineDO);
            distributorMapper.increFieldTeamNum(distributorDO.getId(), 1);
            return count;
        } else {
            return 0;
        }
    }

    @Transactional
    @Override
    public int relate(String inviteCode){
        DistributorDO distributorDO = distributorMapper.selectByInviteCode(inviteCode);
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        MemberUserRespDTO user = memberUserApi.getUser(userId).getCheckedData();
        DistributeDownlineDO downlineDO = new DistributeDownlineDO();
        downlineDO.setParentId(distributorDO.getId());
        downlineDO.setChildId(BigInteger.valueOf(userId));
        downlineDO.setLevel((byte)1);
        downlineDO.setNickname(user.getNickname());
        downlineDO.setMobile(user.getMobile());
        downlineDO.setAvatar(user.getAvatar());
        DistributeDownlineDO downlineDOExist = downlineMapper.selectByChildId(downlineDO.getChildId());
        int count = 0;
        if (downlineDOExist == null) {
             count = downlineMapper.insert(downlineDO);
            distributorMapper.increFieldTeamNum(distributorDO.getId(), 1);
        }
        return count;
    }

    @Override
    public PageResult<DistributeDownlineRespVO> selectAdminPage(DistributeDownlinePageReqVO reqVO) {
        IPage<DistributeDownlineRespVO> mpPage = MyBatisUtils.buildPage(reqVO);
        downlineMapper.selectAdminPage(reqVO,mpPage);

        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal(),  mpPage.getPages());
    }

    @Override
    public List<DistributeDownlineExcelVO> getExportDownlineList(DistributeDownlinePageReqVO reqVO){
        return downlineMapper.getExportDownlineList(reqVO);
    }

}
